﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Validation;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Models;

namespace DbHelper
{
    /// <summary>
    /// sqlserver ef
    /// </summary>
    public class EFHelper
    {
        public xsEntities Context;

        public EFHelper()
        {
            this.Context = new xsEntities();

        }

        public T Update<T>(T entity) where T : class
        {

            var set = Context.Set<T>();
            set.Attach(entity);
            Context.Entry<T>(entity).State = EntityState.Modified;
            Context.SaveChanges();

            return entity;
        }

        public T UpdateEntityFields<T>(T entity, List<string> fileds) where T : class
        {
            if (entity != null && fileds != null)
            {

                try
                {
                    Context.Set<T>().Attach(entity);
                    var SetEntry = ((IObjectContextAdapter)Context).ObjectContext.
                        ObjectStateManager.GetObjectStateEntry(entity);
                    foreach (var t in fileds)
                    {
                        SetEntry.SetModifiedProperty(t);
                    }
                    if (Context.Entry<T>(entity).State == EntityState.Unchanged)
                        Context.Entry<T>(entity).State = EntityState.Modified;
                    ((IObjectContextAdapter)Context).ObjectContext.SaveChanges();
                    //context.SaveChanges();
                    // 写数据库
                }
                catch (DbEntityValidationException dbEx)
                {
                }
            }
            return entity;
        }


        public T Insert<T>(T entity) where T : class
        {
            Context.Set<T>().Add(entity);
            Context.SaveChanges();
            return entity;
        }

        public void Delete<T>(T entity) where T : class
        {
            Context.Entry<T>(entity).State = EntityState.Deleted;
            Context.SaveChanges();
        }

        public int RemoveMore<T>(System.Linq.Expressions.Expression<Func<T, bool>> predicate = null) where T : class
        {
            var set = Context.Set<T>().AsQueryable();
            set = (predicate == null) ? set : set.Where(predicate);

            int i = 0;
            foreach (var item in set)
            {
                Delete<T>(item);
                i++;
            }
            return i;
        }
        public T Find<T>(params object[] keyValues) where T : class
        {
            return Context.Set<T>().Find(keyValues);
        }
        public int Count<T>(System.Linq.Expressions.Expression<Func<T, bool>> predicate = null) where T : class
        {
            return Context.Set<T>().Count(predicate);
        }

        public List<T> FindAll<T>(Expression<Func<T, bool>> conditions = null) where T : class
        {
            if (conditions == null)
                return Context.Set<T>().ToList();
            else
            {
                var query = Context.Set<T>().Where(conditions);
                return query.ToList();
            }
        }

        public List<T> FindAll<T, S>(Expression<Func<T, bool>> conditions, Expression<Func<T, S>> orderBy, bool desc) where T : class
        {
            if (desc)
            {
                return Context.Set<T>().Where(conditions).OrderByDescending(orderBy).ToList();
            }
            else
            {
                return Context.Set<T>().Where(conditions).OrderBy(orderBy).ToList();
            }
        }
        /// <summary>
        /// 不从缓存中查询
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="conditions"></param>
        /// <returns></returns>
        public List<T> FindAsNoTracking<T>(Expression<Func<T, bool>> conditions = null) where T : class
        {
            if (conditions == null)
                return Context.Set<T>().AsNoTracking().ToList();
            else
            {
                var query = Context.Set<T>().AsNoTracking().Where(conditions);
                return query.ToList();
            }
        }

        public void Dispose()
        {
            this.Context.Dispose();
        }
    }
}
